/**
 * Created with JetBrains PhpStorm.
 * User: jiangshuguang
 * Date: 14-10-19
 * Time: 下午2:29
 * 所有ui的基类
 * 如果需要通用的方法，可以在这里添加
 */

(function(){
    var P = window.P,
        oo,Base;

    Base = function(){
        this._createUi = function(options){
            this._data = oo.extend(this._data,options);
            this._callbacks = [];
            this._create();
            this._init();
        };

        /**
         * 预留给子类实现
         * 类似抽象函数
         * @private
         */
        this._init = function(){};
        this._create = function(){};

    };

    Base.prototype = {
        /**
         * 把set & get的方法统一，并且暴露给外部
         * @param key
         * @param value
         * @returns {*}
         */
        data : function(key,value){
            var _data = this._data;
            if(key instanceof  Object){
                oo.extend(_data,key);
                return _data;
            }else if(!!key){
                return value !== undefined ? _data[key] = value : _data[key];
            }else{
                return _data;
            }
        },

        _createGid:function(){

        },

        /**
         * 唯一id，目前采用自增的方式
         */
        getGid:function(){
            return this._gid;
        },

        /**
         * 忽略大小写
         * @param key
         * @private
         */
        _caseGet:function(key){
            for(var name in this._data){
                if(this._data.hasOwnProperty(name) && key.toLowerCase() == name.toLowerCase()){
                    return this._data[name];
                }
            }
            return false;
        },

        /**
         * 事件预留容器
         * @type {{}}
         * @private
         */
        _callbacks : [],

        /**
         * 绑定事件
         * @param    {String}      ev          事件名
         * @param    {Function}    callback    事件处理函数
         * @param    {Object}      context     上下文对象
         */
        bind : function(ev,callback,context){
            ev = ev.toLowerCase();
            var callbacks = this._callbacks,
                list = callbacks[ev] || (callbacks[ev] = []);
            list.push([callback,context]);
            return this;
        },

        /**
         * 与bind保持类似的方法
         */
        on:function(){
            return this.bind.apply(this,arguments);
        },

        /**
         * 执行一次
         * @param ev
         * @param callback
         * @param context
         * @returns {*}
         */
        one:function(ev,callback,context){
            var me = this,once;
            once = function(){
                me.off(ev,callback);
                return callback.apply(context||me,arguments);
            };
            return this.bind.call(this,ev,once,context);
        },

        /**
         * 注销事件
         * @param    {String}      ev          事件名  为空，清除所有的事件
         * @param    {Function}    callback    事件处理函数
         */
        off : function(ev,callback){
            var callbacks;
            if(!ev){
                this._callbacks = {};
            }else if(callbacks = this._callbacks){
                ev = ev.toLowerCase();
                if(!callback){
                    callbacks[ev] = [];
                }else{
                    var list = callbacks[ev];
                    if(!list)return this;
                    for(var i=0, len=list.length;i<len;i++){
                        if(list[i] && callback === list[i][0]){
                            list[i] = null;
                            break;
                        }
                    }
                }
            }
            return this;
        },

        /**
         * 触发事件
         * @param    {String}      ev             事件名
         * @param    {All}         arguments      需要传递的参数
         */
        trigger : function(ev){
            var type = ev.toLowerCase(),
                handler = this._caseGet('on' + type),
                args = Array.prototype.slice.call(arguments).slice(1),
                callbacks = this._callbacks,
                list,callback;

            handler && handler.apply(this, args);
            if(!type){
                return this;
            }else if(list = callbacks[type]){
                for(var i=0;i<list.length;i++){
                    callback = list[i];
                    callback[0].apply(callback[1] || this, args);
                }
                return this;
            }
            return this;
        },

        /**
         *获取根元素
         * @returns {*}
         */
        widget:function(){
            return this.data("$root");
        },

        /**
         * todo 很重要
         * dom && 事件销毁
         * @returns {*}
         */
        destroy:function(){
            this.trigger("destroy");
            return this;
        },

        /**
         * todo 这种方法不完善，如果能不传fun更好
         * 实现面向对象的super方法
         */
        callParent:function(fun,arg){
            return this.__super__[fun] && this.__super__[fun].apply(this,arg);
        }
    };

    /**
     * 内部使用的工具方法
     * @type {{inherits: Function, extend: Function}}
     */
    oo = {
        extend:function(){
            if(arguments.length){
                var ext = arguments[0];
                for(var i=1,len=arguments.length;i<len;i++){
                    for(var name in arguments[i]){
                        if(arguments[i].hasOwnProperty(name)){
                            ext[name] = arguments[i][name];
                        }
                    }
                }
                return ext;
            }
            return null;
        }
    };

    /**
     * todo 继承
     * class工厂
     * @param proto
     * @param Super
     * @returns {Function}
     */
    P.createUi = function(proto,Super){
        var base, o,_super,_data;
        base = new Base();
        o = function(options){
            _data = _data?_data:{};
            options = options?options:{};
            oo.extend(options,_data);
            base._createUi.call(this,options);
        };
        o.prototype = base;
        if(Super){
            _super = Super.prototype;
            o.prototype.__super__ = _super;
            o.prototype._create = _super._create;
            o.prototype._init = _super._init;
            _data = _super._data;
        }
        oo.extend(o.prototype,proto);
        return o;
    };

    /**
     * page 级别自动生成
     * @param options
     * @param pageName
     */
    P.createPage = function(options,pageName){
        var Page = P.createUi(options);
        pageName = pageName?Math.random():pageName;
        P['_page_'+pageName] = new Page();
        return  P['_page_'+pageName];
    }
})();
